﻿
using System;
using System.Collections.Generic;
using System.Diagnostics;
using D2D2.Server.Networking;
using D2D2.SharedInterfaces.Networking;
using Microsoft.Xna.Framework;

namespace D2D2.Server.Core
{
    public class BattlefieldServer
    {
        private const int OFFSET_Y = 100;

        private ServerManager _serverManager;
        private MonsterManagerServer _monsterManager;
        private DropManagerServer _dropManager;

        private int _xres = 1024;
        private int _yres = 768;

        private Random _rand = new Random();
        private ChestManagerServer _chestManager;

        public BattlefieldServer(ServerManager serverManager)
        {
            _serverManager = serverManager;
            _dropManager = new DropManagerServer(_serverManager);
            _monsterManager = new MonsterManagerServer(_serverManager, _dropManager);
            _chestManager = new ChestManagerServer(_serverManager, _dropManager);
        }

        public void Generate(int rows, int columns)
        {
            Vector2 battlefieldLocation = new Vector2(0, OFFSET_Y);
            int cellWidth = (_xres - (int) battlefieldLocation.X)/columns;
            int cellHeight = (_yres - (int) battlefieldLocation.Y)/rows;

            int maxSpriteWidth = 80;
            int maxSpriteHeight = 80;

            List<Vector2> cells = new List<Vector2>();
            int count = rows*columns;

            for (int x = 0; x < columns; x++)
                for (int y = 0; y < rows; y++)
                    cells.Add(new Vector2 {X = x, Y = y});

            for (int i = 0; i < 15; i++)
            {
                int cellIndex = _rand.Next(0, count);
                Vector2 cell = cells[cellIndex];

                Vector2 cellLocation = new Vector2(cell.X*cellWidth, cell.Y*cellHeight + OFFSET_Y);

                Vector2 maxSpriteLocation = new Vector2(cellLocation.X + (cellWidth - maxSpriteWidth),
                                                        cellLocation.Y + (cellHeight - maxSpriteHeight));

                int xSpriteLocation = _rand.Next((int) cellLocation.X, (int) maxSpriteLocation.X);
                int ySpriteLocation = _rand.Next((int) cellLocation.Y, (int) maxSpriteLocation.Y);

                if (i < 10)
                    _serverManager.SendMessage(CreateMonster(xSpriteLocation, ySpriteLocation));
                else
                    _serverManager.SendMessage(CreateChest(xSpriteLocation, ySpriteLocation));

                cells.RemoveAt(cellIndex);
                count--;
            }

        }

        public void Update (float elapsed)
        {
            _monsterManager.Update(elapsed);
            _chestManager.Update(elapsed);
        }

        public void HandleMouseClick(MouseMessage mouseMessage)
        {
            foreach (MonsterObject monster in _monsterManager.Monsters)
            {
                Rectangle rectangle = new Rectangle((int) monster.Location.X, (int) monster.Location.Y,
                                                    monster.GetWidth(),
                                                    monster.GetHeight());

                if (rectangle.Contains(mouseMessage.X, mouseMessage.Y))
                {
                    PlayerObject player = _serverManager.PlayerManager.GetPlayer(mouseMessage.PlayerId);
                    _monsterManager.Hit(player, monster, mouseMessage.MessageTime);
                }
            }

            foreach (ChestObject chest in _chestManager.Chests)
            {
                Rectangle rectangle = new Rectangle((int) chest.Location.X, (int) chest.Location.Y,
                                                    chest.GetWidth(),
                                                    chest.GetHeight());

                if (rectangle.Contains(mouseMessage.X, mouseMessage.Y))
                {
                    PlayerObject player = _serverManager.PlayerManager.GetPlayer(mouseMessage.PlayerId);
                    _chestManager.Hit(player, chest);
                }
            }
        }

        private ChestObject CreateChest(int x,int y)
        {
            ChestObject chest = _chestManager.AddChest(new Vector2(x, y));

            return chest;
        }

        private MonsterObject CreateMonster(int x, int y)
        {
            MonsterView view =(MonsterView) _rand.Next(1, 3);
            MonsterObject monster = _monsterManager.AddMonster(MonsterType.Common, view, 1, new Vector2(x, y));

            return monster;
        }
    }
}
